<template>
  <view v-if="props.expanding">
    <el-checkbox-group
      v-if="props.multiple"
      v-model="state.value"
      :disabled="disabled"
      @change="handleChange"
    >
      <el-checkbox
        v-for="(item, index) in state.options"
        :key="index"
        :label="getOptionLabel(item)"
        :value="getOptionValue(item)"
      />
    </el-checkbox-group>
    <el-radio-group
      v-else
      v-model="state.value"
      :disabled="disabled"
      @change="handleChange"
    >
      <el-radio
        v-for="(item, index) in state.options"
        :key="index"
        :label="getOptionLabel(item)"
        :value="getOptionValue(item)"
      />
    </el-radio-group>
  </view>
  <el-select
    v-else
    v-model="state.value"
    :disabled="disabled"
    :multiple="multiple"
    clearable
    filterable
    :remote="state.remote"
    :remote-method="queryRemote"
    :loading="state.loading"
    :placeholder="placeholder"
    :style="state.style"
    @change="handleChange"
  >
    <el-option
      v-for="(item, index) in state.options"
      :key="index"
      :label="getOptionLabel(item)"
      :value="getOptionValue(item)"
    />
  </el-select>
</template>
<script setup lang="ts" name="CommonSelect">
import { api } from "@/api/common/";
import { isArray, isBlank } from "@/utils/validate";

const props = defineProps({
  // 文字提示
  placeholder: {
    type: String,
    default: function () {
      return "输入后检索";
    }
  },
  width: {
    type: Number,
    default: function () {
      return 160;
    }
  },
  // 是否自动加载数据
  autoQuery: {
    type: Boolean,
    default: function () {
      return false;
    }
  },
  disabled: {
    type: Boolean,
    default: function () {
      return false;
    }
  },
  multiple: {
    type: Boolean,
    default: function () {
      return false;
    }
  },
  expanding: {
    type: Boolean,
    default: function () {
      return false;
    }
  },
  label: {
    type: String,
    default: "label"
  },
  value: {
    type: String,
    default: "value"
  },
  url: {
    type: String,
    default: ""
  },
  queryParams: {
    type: Object,
    default: function () {
      return undefined;
    }
  }
});

const defaultValue = defineModel("defaultValue");
const emits = defineEmits(["change", "loaded"]);

const transferValue = newValue => {
  let tval = null;
  if (props.multiple) {
    if (isBlank(newValue)) {
      tval = [];
    } else if (isArray(newValue)) {
      tval = newValue;
    } else {
      tval = newValue.split(",");
    }
  } else {
    if (isBlank(newValue)) {
      tval = "";
    } else if (isArray(newValue)) {
      tval = newValue.join(",");
    } else {
      tval = newValue;
    }
  }
  return tval;
};

const getOptionLabel = (item: string) => {
  if (item) {
    const labels = props.label.split(",");
    let labelText = "";
    if (labels.length > 1) {
      for (var i = 0; i < labels.length; i++) {
        if (i === 0) {
          labelText = labelText + item[labels[i]];
        } else {
          labelText = labelText + "-" + item[labels[i]];
        }
      }
    } else {
      labelText = item[labels[0]];
    }
    return labelText;
  } else {
    return "lable";
  }
};

const getOptionValue = item => {
  if (item) {
    return item[props.value];
  } else {
    return "value";
  }
};

const state = reactive({
  loading: false,
  options: [],
  remote: props.autoQuery ? false : true,
  value: transferValue(defaultValue.value),
  style: { width: `${props.width}px !important` }
});

onMounted(async () => {
  await initQuery();
});

const queryRemote = query => {
  if (query) {
    state.loading = true;
    const queryParams = {};
    if (props.queryParams) {
      Object.assign(queryParams, props.queryParams);
    }
    queryParams[props.label] = query;
    api(props.url, queryParams)
      .then(res => {
        if (res.code === 200) {
          state.options = res.data;
        }
      })
      .catch(err => {
        console.log(`init:${err}`);
      })
      .finally(() => {
        emits("loaded");
        state.loading = false;
      });
  } else {
    state.options = [];
  }
};

const initQuery = async () => {
  if (props.autoQuery) {
    const queryParams = {};
    if (props.queryParams) {
      Object.assign(queryParams, props.queryParams);
    }
    state.loading = true;
    api(props.url, queryParams)
      .then(res => {
        if (res.code === 200) {
          state.options.push(...(res.data as any[]));
        }
      })
      .catch(err => {
        console.log(`init:${err}`);
      })
      .finally(() => {
        emits("loaded");
        state.loading = false;
      });
  }
};

const setValue = val => {
  state.value = transferValue(val);
};

const getValue = () => {
  return state.value;
};

const handleChange = val => {
  if (props.multiple) {
    if (val && val.length > 0) {
      const options = state.options.filter(item => {
        return val.includes(item[props.value]);
      });
      if (options) {
        defaultValue.value = val.join(",");
        emits("change", val.join(","), options);
      } else {
        defaultValue.value = val.join(",");
        emits("change", val.join(","));
      }
    } else {
      defaultValue.value = "";
      emits("change", "");
    }
  } else {
    if (!isBlank(val)) {
      const actValue = transferValue(val);
      const options = state.options.filter(item => {
        return item[props.value] === actValue;
      });
      if (options) {
        defaultValue.value = val;
        emits("change", val, options[0]);
      } else {
        defaultValue.value = val;
        emits("change", val);
      }
    } else {
      defaultValue.value = "";
      emits("change", "");
    }
  }
};

// 重新加载数据，供父页面调用
const reload = () => {
  initQuery();
};

const getOptions = () => {
  return state.options;
};

watch(
  () => props.url,
  val => {
    initQuery();
  }
);

watch(
  () => defaultValue.value,
  val => {
    state.value = transferValue(val);
  }
);

defineExpose({
  reload,
  setValue,
  getValue,
  getOptions
});
</script>

<style lang="scss" scoped />
